package com.ruoyi.app.service.impl

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.date.DateUtil
import cn.hutool.core.util.NumberUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.shaun.core.context.ProfileHolder
import com.baomidou.shaun.core.mgt.SecurityManager
import com.ruoyi.app.common.*
import com.ruoyi.app.domain.dto.CompleteMemberTaskDto
import com.ruoyi.app.domain.vo.*
import com.ruoyi.app.service.AdvertisingApiService
import com.ruoyi.app.service.UserApiService
import com.ruoyi.back.domain.*
import com.ruoyi.back.domain.dto.UserMemberOrderDto
import com.ruoyi.back.domain.v2.MemberTask
import com.ruoyi.back.domain.v2.TaskCodeShare
import com.ruoyi.back.domain.v2.TaskShare
import com.ruoyi.back.domain.v2.UserMemberTask
import com.ruoyi.back.enums.PayStatusEnum
import com.ruoyi.back.enums.UnitTypeEnum
import com.ruoyi.back.enums.UserTypeEnum
import com.ruoyi.back.service.*
import com.ruoyi.common.core.page.PageDomain
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
class UserApiServiceImpl : UserApiService {

    @Autowired
    private lateinit var appUserService: AppUserService

    @Autowired
    private lateinit var userMemberService: UserMemberService

    @Autowired
    private lateinit var securityManager: SecurityManager

    @Autowired
    private lateinit var userRecordService: UserRecordService

    @Autowired
    private lateinit var userMemberOrderService: UserMemberOrderService

    @Autowired
    private lateinit var contactWayService: ContactWayService

    @Autowired
    private lateinit var appVersionInfoService: AppVersionInfoService

    @Autowired
    private lateinit var memberService: MemberService

    @Autowired
    private lateinit var imageTextShareService: ImageTextShareService

    @Autowired
    private lateinit var urlShareService: UrlShareService

    @Autowired
    private lateinit var clubJobDataService: ClubJobDataService

    @Autowired
    private lateinit var clubJobService: ClubJobService

    @Autowired
    private lateinit var advertisingApiService: AdvertisingApiService


    @Autowired
    private lateinit var memberTaskService: MemberTaskService

    @Autowired
    private lateinit var userMemberTaskService: UserMemberTaskService

    @Autowired
    private lateinit var taskCodeShareService: TaskCodeShareService

    @Autowired
    private lateinit var taskShareService: TaskShareService

    @Autowired
    private lateinit var taskService: TaskService


    override fun userIndexData(): Data<UserIndexData> =
        Ok("获取用户页数据成功", UserIndexData().apply {
            userInfo = ProfileHolder.getProfile().run {
                appUserService.getById(id)?.let {
                    AppUserDetail().apply {
                        BeanUtil.copyProperties(it, this)
                        loginType = it.loginType?.loginType()
                        registerDate = it.registerDate?.format()
                        userType = it.userType?.userType()
                        memberDate = userMemberService.getUserMemberByUserId(it.id!!)
                            ?.run { "${beginMemberDate?.format()}至${endMemberDate?.format()}" } ?: "--"
                        memberName = userMemberOrderService.getUserLastOrderName(it.id!!)

                        it.userType.takeIf { it == UserTypeEnum.MEMBER.code }
                            ?.run {
                                userMemberService.getUserMemberByUserId(it.id!!)
                                    ?.let {
                                        member = true
                                        expireDate = it.endMemberDate?.format()
                                    }
                            } ?: run {
                            member = false
                        }

                        changeFaceRemainCount = if ((it.totalChangeFaceCount ?: 0) - (it.changeFaceRemainCount ?: 0) < 0) 0 else (it.totalChangeFaceCount ?: 0) - (it.changeFaceRemainCount ?: 0)
                        totalChangeFaceCount = it.totalChangeFaceCount ?: 0
                    }
                }
            }
            clubJob = clubJobService.list(
                KtQueryWrapper(ClubJob::class.java)
                    .eq(ClubJob::isShow, true)
                    .orderByDesc(ClubJob::createTime)
            )
                .takeIf { it.isNotEmpty() }
                ?.run {
                    map {
                        AppClobJobVo().apply {
                            BeanUtil.copyProperties(it, this)
                        }
                    }
                }
            userBanner = advertisingApiService.getAdvertisingList(5)
        })

    override fun updateUserFirstInstallationData(firstInstallationData: String): Data<Boolean> =
        appUserService.getById(ProfileHolder.getProfile().id)?.let {
            Ok("更新成功", appUserService.updateById(it.apply { it.firstInstallationData = firstInstallationData }))
        } ?: Fail("不存在此用户")

    override fun logout(): Data<Boolean> =
        ProfileHolder.getProfile().run {
            //1. 删除所有使用记录
            userRecordService.remove(
                KtQueryWrapper(UserRecord::class.java)
                    .eq(UserRecord::createBy, id)
            )

            userMemberOrderService.remove(
                KtQueryWrapper(UserMemberOrder::class.java)
                    .eq(UserMemberOrder::createBy, id)
            )

            userMemberService.remove(
                KtQueryWrapper(UserMember::class.java)
                    .eq(UserMember::createBy, id)
            )

            //2. 注销vip
            appUserService.remove(
                KtQueryWrapper(AppUser::class.java)
                    .eq(AppUser::id, id)
            )

            //3. 删除账号信息
            securityManager.logout(this)

            Ok("注销成功", true)
        }

    override fun exit(): Data<String> = securityManager.logout(ProfileHolder.getProfile()).run { Ok("退出成功") }

    override fun getAppVersionInfo(): Data<AppVersionInfoVo> =
        appVersionInfoService.getOne(
            KtQueryWrapper(AppVersionInfo::class.java)
                .orderByDesc(AppVersionInfo::createTime)
                .last("limit 1")
        )?.run { Ok("获取版本信息成功", AppVersionInfoVo().apply { BeanUtil.copyProperties(this@run, this) }) }
            ?: Fail(201, "暂无版本信息")

    override fun getContactWayList(): Data<List<ContactWayVo>> =
        contactWayService.list(
            KtQueryWrapper(ContactWay::class.java)
                .eq(ContactWay::isShow, true)
                .orderByDesc(ContactWay::createTime)
        )
            .takeIf { it.isNotEmpty() }
            ?.run {
                Ok("获取联系方式列表成功", map {
                    ContactWayVo().apply {
                        BeanUtil.copyProperties(it, this)
                    }
                })
            } ?: Fail(201, "暂无联系方式列表")

    override fun getMemberTypeList(): Data<List<MemberVo>> =
        memberService.list(
            KtQueryWrapper(Member::class.java)
                .eq(Member::isShow, true)
                .ne(Member::type, 3)
                .eq(Member::setChoose, false)
                .orderByAsc(Member::orderNum)
        )
            .takeIf { it.isNotEmpty() }
            ?.run {
                Ok("获取会员类型列表成功",
                    kotlin.run {
                        memberService.getOne(
                            KtQueryWrapper(Member::class.java)
                                .eq(Member::setChoose, true)
                        )
                            ?.let { this.add(0, it) }
                        map {
                            MemberVo().apply {
                                memberId = it.id
                                name = "开通${it.name}"
                                type = it.type
                                order = it.orderNum
                                changeFaceCountDesc = it.receiveCount?.run {
                                    "${it.receiveCount}${
                                        when ((it.receiveUnit)) {
                                            2 -> "分钟"
                                            else -> "次"
                                        }
                                    }"
                                }
                                it.type.takeIf { it == 2 }?.run {
                                    middlePrice = "￥${middlePrice(it.price!!, it.period!!, it.periodUnit!!)}/月"
                                    price = "￥${it.price}/${it.name}"
                                    oldPrice = "￥${it.oldPrice}/${it.name}"
                                } ?: kotlin.run {
                                    obtain = memberService.getById(it.id)?.receiveCount?.minus(
                                        userMemberOrderService.count(
                                            KtQueryWrapper(UserMemberOrder::class.java)
                                                .eq(UserMemberOrder::createBy, ProfileHolder.getProfile().id.toLong())
                                                .eq(UserMemberOrder::memberId, memberId)
                                        )
                                    ) == 0
                                }
                            }
                        }
                    }
                )
            } ?: Ok("暂无数据", null)

    override fun getExperienceTaskType(memberId: Long): Data<ExperienceDetail> =
        memberService.getById(memberId)?.let {
            Ok("获取体验会员详情成功", kotlin.run {
                ExperienceDetail().apply {
                    this.memberId = it.id
                    remainingCount = it.receiveCount?.minus(
                        userMemberOrderService.count(
                            KtQueryWrapper(UserMemberOrder::class.java)
                                .eq(UserMemberOrder::createBy, ProfileHolder.getProfile().id.toLong())
                                .eq(UserMemberOrder::memberId, memberId)
                        )
                    )
                    memberTaskList = memberTaskService.list(
                        KtQueryWrapper(MemberTask::class.java)
                            .eq(MemberTask::memberId, memberId)
                    ).takeIf { it.isNotEmpty() }
                        ?.run {
                            map {
                                it.apply {
                                    haveCompleteCount = userMemberTaskService.getOne(
                                        KtQueryWrapper(UserMemberTask::class.java)
                                            .eq(UserMemberTask::memberId, memberId)
                                            .eq(UserMemberTask::taskId, taskId)
                                            .eq(UserMemberTask::createBy, ProfileHolder.getProfile().id.toLong())
                                    )
                                        ?.haveCompleteCount ?: 0
                                    if (haveCompleteCount == completeCount) {
                                        boolComplete = true
                                    }
                                    taskService.getById(it.taskId)?.let { task ->
                                        taskName = task.name
                                        intro = task.intro
                                    }
                                }
                            }
                        }

                    canReceive = memberTaskList?.all { it.boolComplete == true }

                }
            })
        } ?: Fail("不存在当前会员资源")

    override fun receiveMember(memberId: Long): Data<Boolean> =
        Ok("领取会员成功", kotlin.run {

            //1. 生成会员订单
            userMemberOrderService.createUserMemberOrder(UserMemberOrderDto().apply {
                payAmount = 0.0
                channel = appUserService.appUserInfo(ProfileHolder.getProfile().id.toLong())?.source
                this.memberId = memberId
            }).let { userMemberOrder ->
                userMemberOrderService.updateById(userMemberOrder.apply {
                    payDate = Date()
                    payStatus = PayStatusEnum.PAY_SUCCESS.code
                    payAmount = 0.0
                })
            }

            //2. 增加会员时间
            userMemberService.getUserMemberByUserId(ProfileHolder.getProfile().id.toLong())
                ?.run {
                    userMemberService.updateById(this.apply {
                        endMemberDate =
                            DateUtil.offsetDay(this.endMemberDate, memberService.getById(memberId)?.period ?: 0)
                    })
                }
                ?: kotlin.run {
                    val start = DateUtil.date()
                    userMemberService.save(UserMember().apply {
                        createBy = ProfileHolder.getProfile().id.toLong()
                        beginMemberDate = start
                        endMemberDate = DateUtil.offsetDay(start, memberService.getById(memberId)?.period ?: 0)
                    })
                }

            //3. 删除用户做任务记录
            userMemberTaskService.remove(
                KtQueryWrapper(UserMemberTask::class.java)
                    .eq(UserMemberTask::createBy, ProfileHolder.getProfile().id.toLong())
                    .eq(UserMemberTask::memberId, memberId)
            )

            //4. 增加用户换脸点数
            appUserService.getById(ProfileHolder.getProfile().id.toLong())?.let { appUser ->
                appUserService.updateById(appUser.apply {
                    userType = UserTypeEnum.MEMBER.code
                    totalChangeFaceCount = (totalChangeFaceCount ?: 0 ) + (memberService.getById(memberId)?.experienceChangeFace ?: 0)
                })
            }
            true
        })

    override fun completeMemberTask(completeMemberTaskDto: CompleteMemberTaskDto): Data<Boolean> =
        userMemberTaskService.getOne(
            KtQueryWrapper(UserMemberTask::class.java)
                .eq(UserMemberTask::taskId, completeMemberTaskDto.taskId)
                .eq(UserMemberTask::memberId, completeMemberTaskDto.memberId)
                .eq(UserMemberTask::createBy, ProfileHolder.getProfile().id.toLong())
        )
            ?.run {
                if (haveCompleteCount != completeCount) {
                    userMemberTaskService.updateById(this.apply {
                        haveCompleteCount = haveCompleteCount?.plus(1) ?: 1
                    })
                    Ok("完成任务成功", true)
                } else Fail("当前任务次数已经做完, 无需重复做!")
            }
            ?: kotlin.run {
                Ok("完成任务成功", userMemberTaskService.save(UserMemberTask().apply {
                    createBy = ProfileHolder.getProfile().id.toLong()
                    memberId = completeMemberTaskDto.memberId
                    taskId = completeMemberTaskDto.taskId
                    haveCompleteCount = 1
                    completeCount = memberTaskService.getOne(
                        KtQueryWrapper(MemberTask::class.java)
                            .eq(MemberTask::taskId, completeMemberTaskDto.taskId)
                            .eq(MemberTask::memberId, completeMemberTaskDto.memberId)
                    )
                        ?.completeCount
                }))
            }

    // 3天     10元
    // 3

    val middlePrice: (Double, Int, Int) -> Double = { price, period, periodUnit ->

        when (periodUnit) {
            UnitTypeEnum.DAY.code -> NumberUtil.div(price, NumberUtil.div(period.takeIf { it == 0 }?.run { 100 } ?: period, 30, 2), 2).toDouble()
            UnitTypeEnum.MONTH.code -> period.takeIf { it == 0 }?.run { 0.01 } ?: NumberUtil.div(price, period, 2)
                .toDouble()

            UnitTypeEnum.YEAR.code -> NumberUtil.div(price, period * 12, 2).toDouble()
            else -> 0.0
        }
    }

    override fun getImageTextShare(): Data<ImageTextShareVo> =
        imageTextShareService.getOne(
            KtQueryWrapper(ImageTextShare::class.java)
                .last("limit 1")
        )
            ?.run {
                Ok("获取文案分享成功", ImageTextShareVo().apply { BeanUtil.copyProperties(this@run, this) })
            }
            ?: Fail(201, "暂无数据")

    override fun getUrlShare(): Data<UrlShareVo> =
        urlShareService.getOne(
            KtQueryWrapper(UrlShare::class.java)
                .last("limit 1")
        )
            ?.run {
                Ok("获取链接分享成功", UrlShareVo().apply { BeanUtil.copyProperties(this@run, this) })
            }
            ?: Fail(201, "暂无数据")

    override fun addClubJobDataCount(type: Int, clubJobId: Long): Data<Boolean> =
        Ok("操作成功", clubJobDataService.getTodayData(type)?.run {
            clubJobDataService.updateById(this.apply {
                count = this.count?.plus(1) ?: 1
            })
        } ?: kotlin.run {
            clubJobDataService.save(ClubJobData()
                .apply {
                    this.clubJobId = clubJobId
                    count = 1
                    this.type = type
                    DateUtil.date().let {
                        year = DateUtil.year(it)
                        month = DateUtil.month(it)
                        day = DateUtil.dayOfMonth(it)
                    }
                    createBy = ProfileHolder.getProfile().id.toLong()
                })
        })

    override fun getPayRecordList(pageDomain: PageDomain): Data<PageData<AppPayRecordVo>> =
        userMemberOrderService.page(
            Page(pageDomain.pageNum.toLong(), pageDomain.pageSize.toLong()), KtQueryWrapper(UserMemberOrder::class.java)
                .eq(UserMemberOrder::payStatus, PayStatusEnum.PAY_SUCCESS.code)
                .eq(UserMemberOrder::createBy, ProfileHolder.getProfile().id)
                .orderByDesc(UserMemberOrder::createTime)
        ).let { page: Page<UserMemberOrder> ->

            Ok("获取用户支付记录成功", Page<AppPayRecordVo>().apply {
                BeanUtil.copyProperties(page, this)
                records = page.records.takeIf { it.isNotEmpty() }
                    ?.run {
                        map {
                            AppPayRecordVo().apply {
                                BeanUtil.copyProperties(it, this)
                                memberTypeName = memberService.getNameByMemberId(it.memberId!!)
                                payType = it.payType?.payType()
                                payDate = it.payDate?.format()
                            }
                        }
                    }
            }.pageInfo())
        }

    override fun getTaskCodeShare(taskId: Long): Data<AppTaskCodeShareVo> =
        Ok("获取图片分享成功",
            taskCodeShareService.getOne(KtQueryWrapper(TaskCodeShare::class.java).eq(TaskCodeShare::taskId, taskId))
                .run { AppTaskCodeShareVo().apply { BeanUtil.copyProperties(this@run, this) } })

    override fun getTaskShare(taskId: Long): Data<AppTaskShareVo> =
        Ok("获取图片分享成功",
            taskShareService.getOne(KtQueryWrapper(TaskShare::class.java).eq(TaskShare::taskId, taskId))
                .run { AppTaskShareVo().apply { BeanUtil.copyProperties(this@run, this) } })
}

fun main() {
    println(NumberUtil.div(10, 0.1, 2))
}